home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / tcsearch.arc / SEARCH.C
Encoding:
C/C++ Source or Header  |  1987-06-05  |  4.4 KB  |  140 lines

  1. /*     int search(int (*dir_procedure)(),int (*file_procedure)(),char *mask);
  2. **
  3. **                this procedure will visit every subdirectory of the
  4. **                directory where this procedure was called.  each time
  5. **                a directory is entered or exited, the procedure pointer
  6. **                dir_procedure is called.  each directory is searched for files
  7. **                matching    the mask argument.  everytime a file is found matching
  8. **                the mask, the file_procedure pointer is called.
  9. **
  10. **                int (*dir_procedure)(int pass,
  11. **                                            char *dir[MAXDRIVE+MAXPATH+MAXFILE])
  12. **    
  13. **                the dir_procedure is called each time a directory is
  14. **                entered (pass == 1) and after a directory is exited
  15. **                (pass == 2).  dir_procedure is passed two arguments:
  16. **    
  17. **                    ARGUMENTS:
  18. **                    pass = 1 on first entry to directory, pass = 2 on exit.
  19. **                    dir point to directory string.  on pass one it contains the
  20. **                    current working directory.  on pass two it contains the
  21. **                    directory of the exited string;
  22. **    
  23. **                    RETURN:
  24. **                    returns of anything other than 0 terminates search and the
  25. **                 return value is returned by search.
  26. **
  27. **                int (*file_procedure)(struct *ffblk);
  28. **
  29. **                the file_procedure pointer argument is executed each time
  30. **                a new file name is encountered in the directory tree.  ALL
  31. **                files trigger this call (HIDDEN and SYSTEM included).
  32. **                The ffblk structure pointer is passed to the file_procedure
  33. **                so file name and attributes may be tested.
  34. **
  35. **                calls to argument pointers are checked for NULL pointers.
  36. */
  37.  
  38. #include <stdio.h>
  39. #include <alloc.h>
  40. #include <dir.h>
  41. #include <dos.h>
  42.  
  43. int search(int (*dir_procedure)(),int (*file_procedure)(),char *mask)
  44. {
  45.     struct ffblk *item;    /* see page 88 of turboc reference guide            */
  46.     int errcode=0;            /* error code returned by directory find routines   */
  47.     int returncode=0;        /* return code from called procedures               */
  48.     char *dir;                /* current directory string                         */
  49.  
  50.     /* item and dir are allocated storage with malloc to minimize            */
  51.     /* stack ussage durring recusive calls                                   */
  52.     if (((item=(struct ffblk *)malloc(sizeof(struct ffblk))) == NULL) ||
  53.         ((dir=malloc(MAXDRIVE+MAXPATH+MAXFILE))==NULL))
  54.         perror("Search Procedure");
  55.  
  56.     getcwd(dir,MAXDRIVE+MAXPATH);
  57.  
  58.     if(dir_procedure!=NULL)        /* only call procedure if not null            */
  59.         if((returncode=(*dir_procedure)(1,dir))!=0)
  60.             return(returncode);
  61.  
  62.     /*                                                                       */
  63.     /* file loop                                                             */
  64.     /*                                                                       */
  65.  
  66.     errcode=findfirst(mask,item,FA_SYSTEM+FA_HIDDEN);
  67.     while(errcode==0  && returncode==0)
  68.         {
  69.         if (!(item->ff_attrib & FA_DIREC))
  70.             if(file_procedure!=NULL)
  71.                 returncode=(*file_procedure)(item);
  72.         if (!returncode)
  73.             {
  74.             errcode=findnext(item);
  75.             }
  76.         }
  77.  
  78.     /*                                                                       */
  79.     /* directory loop                                                        */
  80.     /*                                                                       */
  81.  
  82.     if (!returncode)
  83.         errcode=findfirst("*.*",item,FA_DIREC+FA_SYSTEM+FA_HIDDEN);
  84.     while(errcode==0 && returncode==0)
  85.         {
  86.         if((item->ff_attrib & FA_DIREC) && (item->ff_name[0]!='.'))
  87.             {
  88.               chdir(item->ff_name);                 /* drop down to subdir              */
  89.  
  90.             /* recursive call */
  91.             returncode=search(dir_procedure,file_procedure,mask);
  92.  
  93.             getcwd(dir,MAXDRIVE+MAXPATH);
  94.  
  95.               chdir("..");                             /* up to parent directory            */
  96.  
  97.             if(dir_procedure!=NULL)                /* pass two call to dir_procedure */
  98.                 if((returncode=(*dir_procedure)(2,dir))!=0)
  99.                     return(returncode);
  100.  
  101.               }
  102.  
  103.         if (!returncode)
  104.             errcode=findnext(item);
  105.         }
  106.     free(item);
  107.     free(dir);
  108.     return(returncode);
  109. }
  110.  
  111. /* 
  112. **        to see how this procedure works, add line:     #define DEBUG
  113. **        at top of file and compile/link with:            tcc search
  114. */ 
  115.  
  116. #ifdef DEBUG
  117.  
  118. int dir_print(int *pass, char *dir)
  119. {
  120.     printf("Directory: %s, pass %1d\n",dir,pass);
  121.     return(0);
  122. }
  123.  
  124. int file_print(struct ffblk *item)
  125. {
  126.     printf("File: %s\n",item->ff_name);
  127.     return(0);
  128. }
  129.  
  130. main(argc,argv)
  131. int argc;
  132. char **argv;
  133. {
  134.     if (argc==2)
  135.         search(dir_print,file_print,argv[1]);
  136.     else
  137.          search(dir_print,file_print,"*.*");
  138. }
  139. #endif
  140.